﻿/* ----------------------------------------------------------------------------
 * Copyright (c) Philip Stears 
 *
 * This source code is subject to terms and conditions of the Microsoft Public 
 * License (Ms-PL).
 * 
 * By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 * 
 * To request a copy of the Microsoft Public License, send a request by email
 * to license@connectbasic.net.
 *
 * This notice must not be removed from this software.
 * ---------------------------------------------------------------------------- */

namespace ConnectBasic.ObjectModel
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Diagnostics;
    using ConnectBasic.Execution;
    using DlrExpression = Microsoft.Linq.Expressions.Expression;

    /// <summary>
    /// Represents a method definition.
    /// </summary>
    [DebuggerDisplay("Method {Name}: {ReturnType.Name}")]
    public class MethodDefinitionNode : NodeBase
    {
        private readonly string mName;
        private readonly UnboundType mReturnType;
        private readonly IList<ParameterDefinition> mParameters;
        private readonly Block mStatements;

        /// <summary>
        /// Initializes a new instance of the <see cref="MethodDefinitionNode" /> class.
        /// </summary>
        /// <param name="name">The name of the method.</param>
        /// <param name="returnType">The return type of the method (or <see cref="UnboundType.Void" /> for a method with no return value).</param>
        /// <param name="parameters">The method's parameters.</param>
        /// <param name="statements">The statements which make up the method body.</param>
        public MethodDefinitionNode(string name, UnboundType returnType, IEnumerable<ParameterDefinition> parameters, params StatementNodeBase[] statements)
            : this(name, returnType, parameters, (IEnumerable<StatementNodeBase>)statements)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="MethodDefinitionNode" /> class.
        /// </summary>
        /// <param name="name">The name of the method.</param>
        /// <param name="returnType">The return type of the method (or <see cref="UnboundType.Void" /> for a method with no return value).</param>
        /// <param name="parameters">The method's parameters.</param>
        /// <param name="statements">The statements which make up the method body.</param>
        public MethodDefinitionNode(string name, UnboundType returnType, IEnumerable<ParameterDefinition> parameters, IEnumerable<StatementNodeBase> statements)
        {
            if (statements == null) throw new ArgumentNullException("statements");

            mName = name;
            mReturnType = returnType ?? UnboundType.Void;
            mParameters = new ReadOnlyCollection<ParameterDefinition>(new List<ParameterDefinition>(parameters ?? ParameterDefinition.EmptyParameters));
            mStatements = new Block(statements);
        }

        /// <summary>
        /// Gets the name of the method.
        /// </summary>
        public string Name
        {
            get
            {
                return mName;
            }
        }

        /// <summary>
        /// Gets the return type of the method.
        /// </summary>
        public UnboundType ReturnType
        {
            get { return mReturnType; }
        }

        /// <summary>
        /// Gets the method's parameters.
        /// </summary>
        public IList<ParameterDefinition> Parameters
        {
            get { return mParameters; }
        }

        /// <summary>
        /// Gets the statements which make up the method body.
        /// </summary>
        public Block Statements
        {
            get { return mStatements; }
        }

        /// <summary>
        /// Overridden to throw <see cref="NotSupportedException" />.
        /// </summary>
        public override DlrExpression Compile(BasicCodeGenerator gen)
        {
            throw new NotSupportedException();
        }
    }
}
